package com.sky.yipinyoufujava.controller;
// 登录注册表


import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.sky.yipinyoufujava.pojo.*;
import com.sky.yipinyoufujava.pojo.from.LoginForm;
import com.sky.yipinyoufujava.pojo.from.ModifyPasswordForm;
import com.sky.yipinyoufujava.pojo.from.RegisterForm;
import com.sky.yipinyoufujava.pojo.from.SentEmailForm;
import com.sky.yipinyoufujava.result.Result;
import com.sky.yipinyoufujava.service.LoginService;
import com.sky.yipinyoufujava.utils.JwtUtil;
import com.sky.yipinyoufujava.utils.RedisKey;
import com.sky.yipinyoufujava.utils.ValidateCodeUtils;
import com.sky.yipinyoufujava.utils.WxService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j


public class Login {
    @Autowired
    private LoginService loginService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private WxService wxService;
    @Value("${wxmini.appid}")
    private String appid;
    @Value("${wxmini.secret}")
    private String secret;

    /**
     * LoginForm 包含账号密码
     */
    @PostMapping("/login")
    private Result getUser(@RequestBody LoginForm loginForm){
        Short sts =  queryUser(loginForm.getUsername());
        if(sts != null){
            User userList = loginService.login(loginForm);
            if (userList == null) {
                return Result.error("密码错误！");
            } else {
//                获取jwp令牌
                Map<String,Object> claims = new HashMap<>();
                claims.put("id",userList.getId());
                claims.put("username",userList.getUsername());
                String token = JwtUtil.genToken(claims);
                // 创建一个新的Map来包含User对象和token
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("userInfo", userList);
                resultMap.put("token", token);
//                将令牌存到 redis
                ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
                operations.set(token,token,12, TimeUnit.HOURS);
                return Result.success(resultMap);
            }
        }else{
            return Result.error("账号不存在！");
        }
    }
    @PostMapping("/getCode")
    private Result getCode(@RequestBody String code){
        log.info("微信授权登录,{}",code);
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
        String replaceUrl = url.replace("{0}", appid).replace("{1}", secret).replace("{2}", code);
        log.info("微信授权登录url,{}",replaceUrl);
        String res = HttpUtil.get(replaceUrl);
        String uuid = UUID.randomUUID().toString();
        ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
        operations.set(RedisKey.wx_SESSION_ID + uuid,res,1,TimeUnit.HOURS);
        Map<String,String> map = new HashMap<>();
        map.put("sessionId",uuid);
        return Result.success(map);
    };

    //    微信注册
    private User wxRegister(@RequestBody WxUserInfo wxUserInfo){
        log.info("微信注册,{}",wxUserInfo);
        try {
            loginService.wxRegister(wxUserInfo);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        User user = loginService.queryUserByOpenId(wxUserInfo.getOpenId());
        return user;
    };

    /**
     * 微信授权登录
     * @param wxAuth
     * @return
     */
    @PostMapping("/wxLogin")
    private Result wxLogin(@RequestBody WxAuth wxAuth){
        log.info("微信授权登录,{}",wxAuth);
        try {
            String json =  wxService.wxDecrypt(wxAuth.getEncryptedData(),wxAuth.getSessionId(),wxAuth.getIv());
            log.info("没有解析，{}",json);
            PhoneNumberInfo phoneNumberInfo = JSON.parseObject(json, PhoneNumberInfo.class);
            WxUserInfo wxUserInfo = new WxUserInfo();
//            录入手机号
            wxUserInfo.setPhone(phoneNumberInfo.getPhoneNumber());
            wxUserInfo.setOpenId(wxAuth.getSessionId());
            wxUserInfo.setUsername(phoneNumberInfo.getPhoneNumber());
            wxUserInfo.setAccountType("微信注册");
            User userList = loginService.queryUserByOpenId(phoneNumberInfo.getPhoneNumber());
            if (userList != null) {
//                登录账号
                log.info("登录账号,{}",userList);
//                创建一个token
//                获取jwp令牌
                Map<String,Object> claims = new HashMap<>();
                claims.put("id",userList.getId());
                claims.put("username",userList.getUsername());
                String token = JwtUtil.genToken(claims);
                // 创建一个新的Map来包含User对象和token
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("userInfo", userList);
                resultMap.put("token", token);
//                将令牌存到 redis
                ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
//                6个小时
                operations.set(token,token,60, TimeUnit.HOURS);
                return Result.success(resultMap);
            }else{
//                注册账号
                log.info("注册账号,{}",wxUserInfo);
//                获取jwp令牌
                User user = wxRegister(wxUserInfo);
                Map<String,Object> claims = new HashMap<>();
                claims.put("id",user.getId());
                claims.put("username",user.getUsername());
                String token = JwtUtil.genToken(claims);
                // 创建一个新的Map来包含User对象和token
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("userInfo", user);
                resultMap.put("token", token);
//                将令牌存到 redis
                ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
                operations.set(token,token,1, TimeUnit.HOURS);
                return Result.success(resultMap);
            }
//            获取 用户唯一标识
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    };

//    修改用户信息

    @PostMapping("/updataUserInfo")
    private Result updataUserInfo(@RequestBody User user){
        log.info("修改用户信息,{}",user);
        loginService.updataUserInfo(user);
        User userList = queryUserId(user.getId());
        return Result.success(userList);
    }

    /**
     * 查询是否有这个账号
     * name = 用户名
     */
    private Short queryUser(String name){
       Short sts = loginService.queryUser(name);
       return sts;
    }

    // 通过 id 查询用户的信息
    private User queryUserId(Object Id){
        User sts = loginService.queryUserId(Id);
        return sts;
    }


    /**
     * 注册用户
     */
    @PostMapping("/register")
    public Result registerUser(@RequestBody RegisterForm registerForm) {
        log.info("注册账户，{}",registerForm);
        // 检查用户是否已存在
        Short sts = queryUser(registerForm.getUsername());
        if (sts != null) {
            return Result.error("用户已存在！");
        }else{
//            校验验证码是否正确
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            String redisCode = operations.get("code");
            // 检查redisCode是否为null
            if (redisCode == null) {
                return Result.error("验证码不存在或已过期！");
            } else if (!redisCode.equals(registerForm.getCode())) {
                return Result.error("验证码错误！");
            } else {
                loginService.registerUser(registerForm);
                return Result.success("注册成功！");
            }
        }
    }

//    修改密码

    @PostMapping("/modifyPassword")
    public Result modifyPassword(@RequestBody ModifyPasswordForm modifyPasswordForm, @RequestHeader("Token") String token){
        log.info("修改密码,{}",modifyPasswordForm);
        //        解析token 获取用户信息
        Map<String, Object> stringObjectMap = JwtUtil.parseToken(token);
        Object UserId = stringObjectMap.get("id");
        User userInfo = queryUserId(UserId);
        log.info("用户信息，{}",userInfo.getPassword());
//        验证旧密码
        if(!userInfo.getPassword().equals(modifyPasswordForm.getOldPassword())){
            return Result.error("旧密码不正确！");
        }
//        校验验证码
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String redisToken = operations.get(token);
        String redisCode = operations.get("code");
        log.info("redisToken=,{},redisCode=,{}",redisToken,redisCode);
        if(modifyPasswordForm.getEmailCode().equals(redisCode) && token.equals(redisToken)){
            loginService.modifyPassword(userInfo.getId(),modifyPasswordForm);
//            移除 redis 的code
            operations.getOperations().delete("code");
            return Result.success("修改成功！");
        }else{
            return Result.error("验证码不正确。");
        }
    }


//    发送邮箱
    @PostMapping("/sentEmail")
    private Result sentEmail(@RequestBody SentEmailForm sentEmailForm, @RequestHeader("Token") String token){
//        解析token 获取用户信息
        Map<String, Object> stringObjectMap = JwtUtil.parseToken(token);
        Object UserId = stringObjectMap.get("id");
        User userInfo = queryUserId(UserId);
        log.info("获取用户信息,{}",userInfo);
//        获取邮箱账号
        String userEmail = userInfo.getEmail();
        if (userEmail == null || userEmail.isBlank()) {
            log.info("未绑定邮箱！,{}",userEmail);
            return Result.error("未绑定邮箱！");
        }
        String msg = "壹品优服家政系统验证码";
//        生成随机的验证码
        String randomCode = ValidateCodeUtils.generateValidateCode(4).toString();
        String context = "欢迎使用壹品优服家政系统，您的验证码为：" + randomCode + ",五分钟有效！,请妥善保管。";
        // 将验证码存到 redis
        ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
        operations.set("code",randomCode,5, TimeUnit.MINUTES);
        loginService.sentEmail(userEmail,msg,context);
        return Result.success("验证码已经发送!请查收");
    }


//    发送指定的邮箱
    @PostMapping("/sentEmailTo")
    private Result sentEmailTo(@RequestBody SentEmailForm sentEmailForm){
        log.info("发送的邮箱，{}",sentEmailForm.getSentEmail());
//        校验 sentEmailForm.getSentEmail() 是否符合 邮箱标准
        if(!ValidateCodeUtils.isEmail(sentEmailForm.getSentEmail())){
            return Result.error("邮箱格式不正确！");
        }
        String msg = "壹品优服家政系统验证码";
//        生成随机的验证码
        String randomCode = ValidateCodeUtils.generateValidateCode(6).toString();
        String context = "欢迎使用壹品优服家政系统，您的验证码为：" + randomCode + ",五分钟有效！,请妥善保管。";
        // 将验证码存到 redis
        ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
        operations.set("code",randomCode,5, TimeUnit.MINUTES);
        loginService.sentEmail(sentEmailForm.getSentEmail(),msg,context);
//        监听请求成功！
        return Result.success("验证码已经发送!请查收");
    }
}
